/*
 * Copyright 2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.springframework.geode.util;

import org.apache.geode.cache.GemFireCache;
import org.apache.geode.cache.Region;
import org.apache.geode.internal.cache.AbstractRegion;
import org.apache.geode.internal.cache.GemFireCacheImpl;

/**
 * Abstract utility class containing different assertions for Apache Geode objects, such as a {@link GemFireCache}
 * or {@link Region}, and so on.
 *
 * @author John Blum
 * @see org.apache.geode.cache.GemFireCache
 * @see org.apache.geode.cache.Region
 * @since 1.3.0
 */
@SuppressWarnings("unused")
public abstract class GeodeAssertions {

	public static <T> AssertThat<T> assertThat(T obj) {
		return () -> obj;
	}

	private static Class<?> nullSafeType(Object obj) {
		return obj != null ? obj.getClass() : null;
	}

	private static String nullSafeTypeName(Class<?> type) {
		return type != null ? type.getName() : null;
	}

	public static String nullSafeTypeName(Object obj) {
		return nullSafeTypeName(nullSafeType(obj));
	}

	@FunctionalInterface
	public interface AssertThat<T> {

		T getSubject();

		default void isNotInstanceOfAbstractRegion() {

			Object subject = getSubject();

			if (subject instanceof AbstractRegion) {
				throw new AssertionError(String.format("[%1$s] is an instance of [%2$s]",
					nullSafeTypeName(subject), AbstractRegion.class.getName()));
			}
		}

		default void isNotInstanceOfGemFireCacheImpl() {

			Object subject = getSubject();

			if (subject instanceof GemFireCacheImpl) {
				throw new AssertionError(String.format("[%1$s] is an instance of [%2$s]",
					nullSafeTypeName(subject), GemFireCacheImpl.class.getName()));
			}
		}
	}
}
